/////////////////////////////////////////////////////////////////////////////
// Name:        ax_settings_librarypage.cpp
// Purpose:     
// Author:      Julian Smart
// Modified by: 
// Created:     09/12/2008 18:03:17
// RCS-ID:      
// Copyright:   (c) Anthemion Software Limited
// Licence:     New BSD License
/////////////////////////////////////////////////////////////////////////////

#include "wx/wx.h"
#include "wx/valgen.h"

#include "ax/ax_utils.h"

////@begin includes
////@end includes

// #include "coverdesigner/coverdesigner.h"
// #include "coverdesigndialog.h"

#include "ax_resource/ax_settings_librarypage.h"
#include "ax_resource/ax_resource_library.h"

////@begin XPM images
////@end XPM images


/*
 * AxLibrarySettingsPage type definition
 */

IMPLEMENT_DYNAMIC_CLASS( AxLibrarySettingsPage, wxPanel )


/*
 * AxLibrarySettingsPage event table definition
 */

BEGIN_EVENT_TABLE( AxLibrarySettingsPage, wxPanel )

////@begin AxLibrarySettingsPage event table entries
    EVT_BUTTON( ID_LIBRARY_PREFERENCES_MAIN_PATH_BROWSE, AxLibrarySettingsPage::OnLibraryPreferencesMainPathBrowseClick )

    EVT_BUTTON( ID_LIBRARY_PREFERENCES_ADD, AxLibrarySettingsPage::OnLibraryPreferencesAddClick )

    EVT_BUTTON( ID_LIBRARY_PREFERENCES_REMOVE, AxLibrarySettingsPage::OnLibraryPreferencesRemoveClick )
    EVT_UPDATE_UI( ID_LIBRARY_PREFERENCES_REMOVE, AxLibrarySettingsPage::OnLibraryPreferencesRemoveUpdate )

    EVT_BUTTON( ID_LIBRARY_PREFERENCES_ADD_FILE_TYPE, AxLibrarySettingsPage::OnLibraryPreferencesAddFileTypeClick )

    EVT_BUTTON( ID_LIBRARY_PREFERENCES_REMOVE_FILE_TYPE, AxLibrarySettingsPage::OnLibraryPreferencesRemoveFileTypeClick )
    EVT_UPDATE_UI( ID_LIBRARY_PREFERENCES_REMOVE_FILE_TYPE, AxLibrarySettingsPage::OnLibraryPreferencesRemoveFileTypeUpdate )

    EVT_BUTTON( ID_LIBRARY_PREFERENCES_RESET, AxLibrarySettingsPage::OnLibraryPreferencesResetClick )

    EVT_BUTTON( ID_LIBRARY_DEFAULT_DESIGN, AxLibrarySettingsPage::OnLibraryDefaultDesignClick )

    EVT_BUTTON( ID_LIBRARY_CONSOLIDATE, AxLibrarySettingsPage::OnLibraryConsolidateClick )
    EVT_UPDATE_UI( ID_LIBRARY_CONSOLIDATE, AxLibrarySettingsPage::OnLibraryConsolidateUpdate )

////@end AxLibrarySettingsPage event table entries

END_EVENT_TABLE()


/*
 * AxLibrarySettingsPage constructors
 */

AxLibrarySettingsPage::AxLibrarySettingsPage()
{
    Init();
}

AxLibrarySettingsPage::AxLibrarySettingsPage(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
{
    Init();
    Create(parent, id, pos, size, style);
}


/*
 * AxLibrarySettingsPage creator
 */

bool AxLibrarySettingsPage::Create(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style)
{
////@begin AxLibrarySettingsPage creation
    wxPanel::Create( parent, id, pos, size, style );

    CreateControls();
    if (GetSizer())
    {
        GetSizer()->SetSizeHints(this);
    }
    Centre();
////@end AxLibrarySettingsPage creation

    return true;
}


/*
 * AxLibrarySettingsPage destructor
 */

AxLibrarySettingsPage::~AxLibrarySettingsPage()
{
////@begin AxLibrarySettingsPage destruction
////@end AxLibrarySettingsPage destruction
}


/*
 * Member initialisation
 */

void AxLibrarySettingsPage::Init()
{
    m_canConsolidate = false;
    m_settings = NULL;
    
////@begin AxLibrarySettingsPage member initialisation
    m_pathCtrl = NULL;
    m_additionalPathsCtrl = NULL;
    m_fileTypesCtrl = NULL;
////@end AxLibrarySettingsPage member initialisation
}


/*
 * Control creation for AxLibrarySettingsPage
 */

void AxLibrarySettingsPage::CreateControls()
{    
////@begin AxLibrarySettingsPage content construction
    AxLibrarySettingsPage* itemPanel1 = this;

    wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
    itemPanel1->SetSizer(itemBoxSizer2);

    wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer2->Add(itemBoxSizer3, 1, wxGROW, 5);

    wxStaticText* itemStaticText4 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Main library path:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer3->Add(itemStaticText4, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL);
    itemBoxSizer3->Add(itemBoxSizer5, 0, wxGROW, 5);

    m_pathCtrl = new wxTextCtrl( itemPanel1, ID_LIBRARY_PREFERENCES_MAIN_PATH, _T(""), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer5->Add(m_pathCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxButton* itemButton7 = new wxButton( itemPanel1, ID_LIBRARY_PREFERENCES_MAIN_PATH_BROWSE, _("&Browse"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer5->Add(itemButton7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticText* itemStaticText8 = new wxStaticText( itemPanel1, wxID_STATIC, _("&Additional paths:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer3->Add(itemStaticText8, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxBoxSizer* itemBoxSizer9 = new wxBoxSizer(wxHORIZONTAL);
    itemBoxSizer3->Add(itemBoxSizer9, 0, wxGROW, 5);

    wxArrayString m_additionalPathsCtrlStrings;
    m_additionalPathsCtrl = new wxListBox( itemPanel1, ID_LIBRARY_PREFERENCES_ADDITIONAL_PATH, wxDefaultPosition, wxSize(-1, 70), m_additionalPathsCtrlStrings, wxLB_SINGLE|wxLB_HSCROLL );
    itemBoxSizer9->Add(m_additionalPathsCtrl, 1, wxGROW|wxALL, 5);

    wxBoxSizer* itemBoxSizer11 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer9->Add(itemBoxSizer11, 0, wxALIGN_CENTER_VERTICAL, 5);

    wxButton* itemButton12 = new wxButton( itemPanel1, ID_LIBRARY_PREFERENCES_ADD, _("&Add"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer11->Add(itemButton12, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);

    wxButton* itemButton13 = new wxButton( itemPanel1, ID_LIBRARY_PREFERENCES_REMOVE, _("&Remove"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer11->Add(itemButton13, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);

    wxStaticText* itemStaticText14 = new wxStaticText( itemPanel1, wxID_STATIC, _("&File types managed by this application:"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer3->Add(itemStaticText14, 0, wxALIGN_LEFT|wxLEFT|wxRIGHT|wxTOP, 5);

    wxBoxSizer* itemBoxSizer15 = new wxBoxSizer(wxHORIZONTAL);
    itemBoxSizer3->Add(itemBoxSizer15, 0, wxGROW, 5);

    wxArrayString m_fileTypesCtrlStrings;
    m_fileTypesCtrl = new wxCheckListBox( itemPanel1, ID_LIBRARY_PREFERENCES_FILE_TYPES, wxDefaultPosition, wxSize(-1, 70), m_fileTypesCtrlStrings, wxLB_SINGLE );
    itemBoxSizer15->Add(m_fileTypesCtrl, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxBoxSizer* itemBoxSizer17 = new wxBoxSizer(wxVERTICAL);
    itemBoxSizer15->Add(itemBoxSizer17, 0, wxALIGN_CENTER_VERTICAL, 5);

    wxButton* itemButton18 = new wxButton( itemPanel1, ID_LIBRARY_PREFERENCES_ADD_FILE_TYPE, _("&Add"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer17->Add(itemButton18, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);

    wxButton* itemButton19 = new wxButton( itemPanel1, ID_LIBRARY_PREFERENCES_REMOVE_FILE_TYPE, _("&Remove"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer17->Add(itemButton19, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT|wxBOTTOM, 5);

    wxFlexGridSizer* itemFlexGridSizer20 = new wxFlexGridSizer(2, 2, 0, 0);
    itemFlexGridSizer20->AddGrowableRow(2);
    itemFlexGridSizer20->AddGrowableCol(0);
    itemFlexGridSizer20->AddGrowableCol(1);
    itemBoxSizer3->Add(itemFlexGridSizer20, 0, wxGROW, 5);

    wxButton* itemButton21 = new wxButton( itemPanel1, ID_LIBRARY_PREFERENCES_RESET, _("&Reset Library"), wxDefaultPosition, wxDefaultSize, 0 );
    itemFlexGridSizer20->Add(itemButton21, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticText* itemStaticText22 = new wxStaticText( itemPanel1, wxID_STATIC, _("This will scan your folders again, deleting all changes you have made."), wxDefaultPosition, wxDefaultSize, 0 );
    itemStaticText22->Wrap(320);
    itemFlexGridSizer20->Add(itemStaticText22, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxButton* itemButton23 = new wxButton( itemPanel1, ID_LIBRARY_DEFAULT_DESIGN, _("Default &Cover"), wxDefaultPosition, wxDefaultSize, 0 );
    itemButton23->Show(false);
    itemFlexGridSizer20->Add(itemButton23, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxStaticText* itemStaticText24 = new wxStaticText( itemPanel1, wxID_STATIC, _("Click to choose a default cover for books with no cover."), wxDefaultPosition, wxDefaultSize, 0 );
    itemStaticText24->Wrap(320);
    itemStaticText24->Show(false);
    itemFlexGridSizer20->Add(itemStaticText24, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);

    wxBoxSizer* itemBoxSizer25 = new wxBoxSizer(wxVERTICAL);
    itemFlexGridSizer20->Add(itemBoxSizer25, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5);

    wxButton* itemButton26 = new wxButton( itemPanel1, ID_LIBRARY_CONSOLIDATE, _("Co&nsolidate"), wxDefaultPosition, wxDefaultSize, 0 );
    itemBoxSizer25->Add(itemButton26, 0, wxGROW|wxALL, 5);

    wxStaticText* itemStaticText27 = new wxStaticText( itemPanel1, wxID_STATIC, _("Small changes to the library are saved separately - click to consolidate into one file."), wxDefaultPosition, wxDefaultSize, 0 );
    itemStaticText27->Wrap(320);
    itemFlexGridSizer20->Add(itemStaticText27, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxALL, 5);

////@end AxLibrarySettingsPage content construction
}

/// Initialize with settings object. Must be called after panel
/// is created.
void AxLibrarySettingsPage::Initialize(AxResourceLibrary* library, AxResourceLibrarySettings* settings)
{
    m_library = library;
    m_settings = settings;

    m_pathCtrl->SetValidator(wxGenericValidator( & m_settings->m_mainLibraryPath));

    PopulateAdditionalPaths();
    CheckConsolidate();
}

/*
 * Should we show tooltips?
 */

bool AxLibrarySettingsPage::ShowToolTips()
{
    return true;
}

/// Check can consolidate library file
void AxLibrarySettingsPage::CheckConsolidate()
{
    if (m_settings && m_library)
    {
        wxString changesFilename = m_settings->GetLibraryChangesDataFile();
        if (wxFileExists(changesFilename) || (m_library->GetModified() && m_library->CanWriteChangesSeparately()))
            m_canConsolidate = true;
        else
            m_canConsolidate = false;
    }
}

/// Lists files in additional paths
void AxLibrarySettingsPage::PopulateAdditionalPaths()
{
    m_additionalPathsCtrl->Clear();
    if (m_settings)
    {
        size_t i;
        for (i = 0; i < m_settings->GetAdditionalLibraryPaths().GetCount(); i++)
        {
            m_additionalPathsCtrl->Append(m_settings->GetAdditionalLibraryPaths()[i]);
        }
    }
}


/*
 * Get bitmap resources
 */

wxBitmap AxLibrarySettingsPage::GetBitmapResource( const wxString& name )
{
    // Bitmap retrieval
////@begin AxLibrarySettingsPage bitmap retrieval
    wxUnusedVar(name);
    return wxNullBitmap;
////@end AxLibrarySettingsPage bitmap retrieval
}

/*
 * Get icon resources
 */

wxIcon AxLibrarySettingsPage::GetIconResource( const wxString& name )
{
    // Icon retrieval
////@begin AxLibrarySettingsPage icon retrieval
    wxUnusedVar(name);
    return wxNullIcon;
////@end AxLibrarySettingsPage icon retrieval
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIBRARY_PREFERENCES_MAIN_PATH_BROWSE
 */

void AxLibrarySettingsPage::OnLibraryPreferencesMainPathBrowseClick( wxCommandEvent& WXUNUSED(event) )
{
    AxUIUtilities::ChooseFolder(m_pathCtrl, this);
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIBRARY_PREFERENCES_ADD
 */

void AxLibrarySettingsPage::OnLibraryPreferencesAddClick( wxCommandEvent& WXUNUSED(event) )
{
    if (m_settings)
    {
        wxString msg = _("Choose a folder");
        wxWindow* parent = wxGetTopLevelParent(this);
        
        wxDirDialog dirDlg(parent, msg, wxEmptyString, wxDD_DEFAULT_STYLE);
        if (dirDlg.ShowModal() == wxID_OK)
        {
            wxString path = dirDlg.GetPath();
            m_additionalPathsCtrl->Append(path);
            m_settings->GetAdditionalLibraryPaths().Add(path);
            m_additionalPathsCtrl->SetSelection(m_additionalPathsCtrl->GetCount()-1);
        }
    }
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIBRARY_PREFERENCES_REMOVE
 */

void AxLibrarySettingsPage::OnLibraryPreferencesRemoveClick( wxCommandEvent& WXUNUSED(event) )
{
    int sel = m_additionalPathsCtrl->GetSelection();
    if (sel != -1)
    {
        m_additionalPathsCtrl->Delete(sel);
        m_settings->GetAdditionalLibraryPaths().RemoveAt(sel);
        if (m_additionalPathsCtrl->GetCount() > 0)
            m_additionalPathsCtrl->SetSelection(0);
    }
}


/*
 * wxEVT_UPDATE_UI event handler for ID_LIBRARY_PREFERENCES_REMOVE
 */

void AxLibrarySettingsPage::OnLibraryPreferencesRemoveUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_additionalPathsCtrl->GetSelection() != -1);
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIBRARY_PREFERENCES_RESET
 */

void AxLibrarySettingsPage::OnLibraryPreferencesResetClick( wxCommandEvent& WXUNUSED(event) )
{
    if (m_library)
    {
        int ans = wxMessageBox(_("Are you sure you want to reset the library?\n\nYou will lose annotations, and it may take some time."),
            _("Reset Library"), wxICON_QUESTION|wxYES_NO, wxGetTopLevelParent(this));
        if (ans == wxNO)
            return;
        
        TransferDataFromWindow();
        
        m_library->RefreshLibrary(true, true, wxGetTopLevelParent(this));
        
        CheckConsolidate();
    }
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIBRARY_DEFAULT_DESIGN
 */

void AxLibrarySettingsPage::OnLibraryDefaultDesignClick( wxCommandEvent& WXUNUSED(event) )
{
    // TODO
#if 0
    shBookInfo info;
    info.m_title = _("The title of the book");
    info.m_author = _("A.N. Author");
    info.m_publisher = _("Acme Publications");
    info.m_id = _("ISBN0000000000");
    info.m_date = _("2008-12-22");

    cdKeywordProvider keywordProvider;
    wxGetApp().GetBookshelfManager().InstantiateKeywords(info, keywordProvider);

    ebCoverDesignDialog dialog(wxGetTopLevelParent(this));
    dialog.SetKeywordProvider(& keywordProvider);
    dialog.m_coverDesignerPanel->SetImageBrowserSettings(& wxGetApp().GetBrowserSettings());
    dialog.GetCoverDesign() = wxGetApp().GetBookshelfManager().GetDefaultCoverDesign();
    dialog.SetTemplateFolder(wxGetApp().GetSettings().GetTemplateFolder());

    if (dialog.ShowModal() == wxID_OK)
    {
        wxGetApp().GetBookshelfManager().GetDefaultCoverDesign() = dialog.GetCoverDesign();
        wxGetApp().GetBookshelfManager().SetModified(true);
        CheckConsolidate();
    }
#endif
}

/// Data transfer
bool AxLibrarySettingsPage::TransferDataToWindow()
{
    wxPanel::TransferDataToWindow();

    if (m_settings)
        m_settings->m_supportedFiles.TransferDataToCheckListBox(m_fileTypesCtrl, false);
    
    return true;
}

bool AxLibrarySettingsPage::TransferDataFromWindow()
{
    wxPanel::TransferDataFromWindow();
    
    if (m_settings)
        m_settings->m_supportedFiles.TransferDataFromCheckListBox(m_fileTypesCtrl);

    return true;
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIBRARY_PREFERENCES_ADD_FILE_TYPE
 */

void AxLibrarySettingsPage::OnLibraryPreferencesAddFileTypeClick( wxCommandEvent& WXUNUSED(event) )
{
    if (GetSettings())
    {
        wxString ext = wxGetTextFromUser(_("Enter the new file type extension."), _("New File Type"), wxEmptyString, wxGetTopLevelParent(this));
        if (ext.IsEmpty())
            return;
        
        if (GetSettings()->GetSupportedFiles().TypeExists(ext))
        {
            wxMessageBox(wxString::Format(_("Sorry, extension %s is already listed."), ext.c_str()), _("New File Type"), wxICON_QUESTION|wxOK, wxGetTopLevelParent(this));
            return;
        }
        
        wxString extUpper(ext.Upper());
        wxString descr(wxString::Format(_("%s files"), extUpper.c_str()));
        
        descr = wxGetTextFromUser(_("Enter a description for the new file type."), _("New File Type"), descr, wxGetTopLevelParent(this));
        if (descr.IsEmpty())
            return;
        
        GetSettings()->GetSupportedFiles().AddFileType(ext, descr, true);
        GetSettings()->GetSupportedFiles().TransferDataToCheckListBox(m_fileTypesCtrl, true);       
        if (m_fileTypesCtrl->GetCount() > 0)
            m_fileTypesCtrl->SetSelection(0);    
    }
}

/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIBRARY_PREFERENCES_REMOVE_FILE_TYPE
 */

void AxLibrarySettingsPage::OnLibraryPreferencesRemoveFileTypeClick( wxCommandEvent& WXUNUSED(event) )
{
    if (GetSettings())
    {
        int sel = m_fileTypesCtrl->GetSelection();
        if (sel != -1)
        {
            wxString ext = GetSettings()->GetSupportedFiles().GetExtension(sel);
            int ans = wxMessageBox(wxString::Format(_("Delete file type %s?"), ext.c_str()), _("Delete File Type"), wxICON_QUESTION|wxYES_NO, wxGetTopLevelParent(this));
            if (ans == wxNO)
                return;
            
            GetSettings()->GetSupportedFiles().RemoveFileType(sel);
            GetSettings()->GetSupportedFiles().TransferDataToCheckListBox(m_fileTypesCtrl, true);       
            if (m_fileTypesCtrl->GetCount() > 0)
                m_fileTypesCtrl->SetSelection(0);
        }
    }
}


/*
 * wxEVT_UPDATE_UI event handler for ID_LIBRARY_PREFERENCES_REMOVE_FILE_TYPE
 */

void AxLibrarySettingsPage::OnLibraryPreferencesRemoveFileTypeUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_fileTypesCtrl->GetSelection() != -1);
}


/*
 * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_LIBRARY_CONSOLIDATE
 */

void AxLibrarySettingsPage::OnLibraryConsolidateClick( wxCommandEvent& WXUNUSED(event) )
{
    if (m_library && m_canConsolidate)
    {
        m_library->SetModified(true);
        m_library->SaveLibrary(true);
        CheckConsolidate();
    }
}


/*
 * wxEVT_UPDATE_UI event handler for ID_LIBRARY_CONSOLIDATE
 */

void AxLibrarySettingsPage::OnLibraryConsolidateUpdate( wxUpdateUIEvent& event )
{
    event.Enable(m_canConsolidate);
}
